package org.xmap.ui.effect;

import javax.microedition.lcdui.Image;
import org.xmap.util.XmapMath;

public final class Fading {

    public static short IMAGE_OPAQUE = 255;
    public static short IMAGE_TRANSPARENT = 0;
    public static boolean LINEAR = true;
    public static boolean QUADRATIC = false;
    // 修改图像的透明度

    public static void blend(int[] raw, short alphaValue) {
        alphaValue <<= 24;
        for (int i = 0; i < raw.length; i++) {
            raw[i] = (raw[i] & 0x00FFFFFF) + alphaValue;
        }
    }
    // row以50%的alpha值和bgRow100%alpha融合

    public static void fastBlend(int[] data, int[] raw, int[] bgRow) {
        for (int i = 0; i < raw.length; i++) {
//            int color1 = raw[i];
//            int r1 = (color1 & 0x00FF0000) >> 16;
//            int g1 = (color1 & 0x0000FF00) >> 8;
//            int b1 = (color1 & 0x000000FF);
//            int color2 = bgRow[i];
//            int r2 = (color2 & 0x00FF0000) >> 16;
//            int g2 = (color2 & 0x0000FF00) >> 8;
//            int b2 = (color2 & 0x000000FF);
//            int r = (r1 >> 1) + (r2 >> 1);
//            int g = (g1 >> 1) + (g2 >> 1);
//            int b = (b1 >> 1) + (b2 >> 1);
//            data[i] = (0xff000000) + (r << 16) + (g << 8) + (b);
            data[i] = (((raw[i] & 0xFEFEFEFE) >> 1) + ((bgRow[i] & 0xFEFEFEFE) >> 1));
        }
    }

    /**
     * 获得渐变矩形
     * @param color - 矩形color
     * @param width - 矩形宽
     * @param height - 矩形高
     * @param left - 矩形左边效果宽
     * @param right - 矩形右边效果宽
     * @return 数据存放在数组中
     */
    public static int[] createTransparentRect(int color, int width, int height, int left, int right,
            boolean mode) {
        int data[] = new int[width * height];
        color &= 0x00FFFFFF;
        for (int h = 0; h < height; h++) {
            int alpha = 0;
            if (mode) {
                alpha = (h << 8) / height;
            } else {
                alpha = (h * h << 8) / (height * height);
            }
            int hColor = color + (alpha << 24);
            int hBase = h * width;
            for (int w = 0; w < width; w++) {
                int alpha2 = alpha;
                int hColor2 = hColor;
                if (w < left) {
                    alpha2 = w * alpha / left;
                    hColor2 = (color + (alpha2 << 24));
                } else if (w >= width - right) {
                    alpha2 = (width - w) * alpha / right;
                    hColor2 = (color + (alpha2 << 24));
                }
                data[hBase + w] = hColor2;
            }
        }
        return data;
    }

    public static Image createTransparentRectImage(int color, int width, int height, int left, int right,
            boolean mode) {
        int[] data = Fading.createTransparentRect(color, width, height, left, right, mode);
        return Image.createRGBImage(data, width, height, true);
    }

    public static int[] createTransparentCirque(int color, int radius, int distance) {
        int bigRadius = radius + distance;
        int smallRadius = radius - distance;
        int bigRadiusSquare = bigRadius * bigRadius;
        int smallRadiusSquare = smallRadius * smallRadius;
        int diameter = bigRadius << 1;
        int data[] = new int[diameter * diameter];
        color &= 0x00FFFFFF;
        for (int h = 0; h < bigRadius; h++) {
            int hBaseUp = h * diameter;
            int hBaseDown = (diameter - h - 1) * diameter;
            for (int w = 0; w < bigRadius; w++) {
                int alpha = 0;
                int distanceSquare = (bigRadius - h) * (bigRadius - h) + (bigRadius - w) * (bigRadius - w);
                if (distanceSquare < bigRadiusSquare && distanceSquare > smallRadiusSquare) {
//                    int d = (int) Math.sqrt(distanceSquare);
                    int d = XmapMath.intSqrt(distanceSquare);
                    alpha = (((distance - Math.abs((d - radius))) * (distance - Math.abs(d - radius)) << 8) / (distance * distance));
                    if (alpha > 0xFF) {
                        alpha = 0xFF;
                    }
                }
                int hColor = color + (alpha << 24);
                data[hBaseUp + w] = hColor;
                data[hBaseUp + diameter - w - 1] = hColor;
                data[hBaseDown + w] = hColor;
                data[hBaseDown + diameter - w - 1] = hColor;
            }
        }
        return data;
    }

    public static Image createTransparentCirqueImage(int color, int radius, int distance) {
        int[] data = Fading.createTransparentCirque(color, radius, distance);
        return Image.createRGBImage(data, (radius + distance) << 1, (radius + distance) << 1, true);
    }

    /**
     * 获得渐变圆形, alpha按距离二次方衰减
     * @param color - 矩形color
     * @param radius - 矩形右边效果宽
     * @return 数据存放在数组中
     */
    public static int[] createTransparentCircle(int color, int radius) {
        int diameter = radius << 1;
        int data[] = new int[diameter * diameter];
        color &= 0x00FFFFFF;
        for (int h = 0; h < radius; h++) {
            int hBaseUp = h * diameter;
            int hBaseDown = (diameter - h - 1) * diameter;
            for (int w = 0; w < radius; w++) {
                int alpha = 0;
                int distanceSquare = (radius - h) * (radius - h) + (radius - w) * (radius - w);
                if (distanceSquare < radius * radius) {
//                    int distance = (int) Math.sqrt(distanceSquare);
                    int distance = XmapMath.intSqrt(distanceSquare);
                    alpha = (((radius - distance) * (radius - distance) << 8) / (radius * radius));
//                    alpha = ((distance) * (distance) * 255 / (radius * radius));
                    if (alpha > 0xFF) {
                        alpha = 0xFF;
                    }
                }
                int hColor = color + (alpha << 24);
                data[hBaseUp + w] = hColor;
                data[hBaseUp + diameter - w - 1] = hColor;
                data[hBaseDown + w] = hColor;
                data[hBaseDown + diameter - w - 1] = hColor;
            }
        }
        return data;
    }

    public static Image createTransparentCircleImage(int color, int radius) {
        int[] data = Fading.createTransparentCircle(color, radius);
        return Image.createRGBImage(data, radius << 1, radius << 1, true);
    }
}
